﻿using System;
using System.Collections.Generic;
using System.Text;
using TvLibrary.Log;
using TvDatabase;

namespace TvServer.Epg
{
    public class Plugin : TvEngine.ITvServerPlugin
    {
        public struct SettingProperties
        {
            public string CheckedChannels
            {
                get
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    return layer.GetSetting(NAME + ".CheckedChannels", "").Value;
                }
                set
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting setting = layer.GetSetting(NAME + ".CheckedChannels");
                    setting.Value = value;
                    setting.Persist();
                }
            }

            public decimal CheckInterval
            {
                get
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting setting = layer.GetSetting(NAME + ".CheckInterval");

                    decimal checkInterval = 1;
                    decimal.TryParse(setting.Value, out checkInterval);

                    return checkInterval;
                }
                set
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting setting = layer.GetSetting(NAME + ".CheckInterval");
                    setting.Value = value.ToString();
                    setting.Persist();
                }
            }

            public DateTime LastRun
            {
                get
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting setting = layer.GetSetting(NAME + ".LastRun");

                    DateTime lastRun = DateTime.MinValue;
                    DateTime.TryParse(setting.Value, out lastRun);

                    return lastRun;
                }
                set
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting setting = layer.GetSetting(NAME + ".LastRun");
                    setting.Value = value.ToString();
                    setting.Persist();
                }
            }

            public string XmlTvPath
            {
                get 
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    return layer.GetSetting("xmlTv", System.IO.Directory.GetCurrentDirectory()).Value;
                }
            }
        }

        const string NAME = "TvServer.Epg";
        const string VERSION = "0.1.0.6";
        const string AUTHOR = "Zenter";
        const bool MASTERONLY = true;

        private System.Timers.Timer _timer;
        public SettingProperties Settings;

        public delegate void MessageEventHandler(string message);

        public event GenerateXmlTvEventHandler XmlTvGenerated;
        public event MessageEventHandler Message;

        #region properties
        /// <summary>
        /// returns the name of the plugin
        /// </summary>
        public string Name
        {
            get { return NAME; }
        }

        /// <summary>
        /// returns the version of the plugin
        /// </summary>
        public string Version
        {
            get { return VERSION; }
        }

        /// <summary>
        /// returns the author of the plugin
        /// </summary>
        public string Author
        {
            get { return AUTHOR; }
        }

        /// <summary>
        /// returns if the plugin should only run on the master server
        /// or also on slave servers
        /// </summary>
        public bool MasterOnly
        {
            get { return MASTERONLY; }
        }
        #endregion

        #region  methods
        /// <summary>
        /// Writes a message to the log
        /// </summary>
        /// <param name="message">The message</param>
        private void WriteLog(string message)
        {
            Log.WriteFile(NAME + ": " + message);

            if(Message != null)
                Message(message); 
        }

        /// <summary>
        /// Starts the plugin
        /// </summary>
        /// <param name="controller"></param>
        public void Start(TvControl.IController controller)
        {
            Start();
        }

        /// <summary>
        /// Starts the plugin
        /// </summary>
        public void Start()
        {
            _timer = new System.Timers.Timer();
            _timer.Interval = 60000 * 60 * (double)Settings.CheckInterval;
            _timer.Enabled = true;
            _timer.Elapsed += new System.Timers.ElapsedEventHandler(GenerateXmlTv);
            WriteLog("Plugin started");

            System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(GenerateXmlTv));
            thread.Start();
        }

        /// <summary>
        /// Generates the XmlTv file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GenerateXmlTv(object sender, System.Timers.ElapsedEventArgs e)
        {
            GenerateXmlTv();
        }

        /// <summary>
        /// Generates the XmlTv file
        /// </summary>
        public void GenerateXmlTv()
        {
            WriteLog("Updating Epg");

            try
            {
                string xmlTvPath = Settings.XmlTvPath;
                string checkedTvChannels = Settings.CheckedChannels;

                XmlTv xmlTv = new XmlTv();

                DrService drService = new DrService();
                
                List<Channel> channelList = drService.GetChannels(ChannelType.Tv);
                foreach (Channel channel in channelList)
                {
                    if (checkedTvChannels.Contains(channel.SourceUrl))
                    {
                        WriteLog("Getting Epg for channel: " + channel.Name + " on " + DateTime.Today.ToShortDateString());
                        List<Schedule> scheduleList = drService.GetSchedules(channel, DateTime.Today);
                        foreach (Schedule schedule in scheduleList)
                            xmlTv.AddProgrammeElement(schedule);
                    }
                }
                WriteLog("XmlTv Path: " + System.IO.Path.Combine(xmlTvPath, "xmltv.xml"));
                xmlTv.Save(System.IO.Path.Combine(xmlTvPath, "xmltv.xml"));

                Settings.LastRun = DateTime.Now;

                WriteLog("Epg updated");
                if (XmlTvGenerated != null)
                    XmlTvGenerated(xmlTv);
            }
            catch (Exception ex)
            {
                WriteLog(ex.ToString());
                Log.Write(ex);
            }

        }

        /// <summary>
        /// Stops the plugin
        /// </summary>
        public void Stop()
        {
            if (_timer != null)
            {
                _timer.Enabled = false;
                _timer.Dispose();
                _timer = null;
            }
            WriteLog("Plugin stopped");
        }

        /// <summary>
        /// Restarts the plugin
        /// </summary>
        public void Restart()
        {
            Stop();
            Start();
        }

        /// <summary>
        /// returns the setup sections for display in SetupTv
        /// </summary>
        public SetupTv.SectionSettings Setup
        {
            get { return new SettingsForm(this); }
        }
        #endregion
    }
}
